/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package controler;

import static java.lang.Thread.sleep;
import java.util.ArrayList;
import java.util.HashMap;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import modele.*;
import view.*;

/**
 * Controleur de l'application : il fait le lien entre la vue et le modèle
 * @author EpsilonE
 */
public class Controleur 
{
    private ArrayList<Joueur> listJoueurs;
    private Plateau plateau;
    private Joueur joueurCourant;
    private int numJoueurCourant;
    private MainFrame mainFrame;
    private FrameNewPartie newPartieFrame;
    private FrameNewPlayer newPlayerFrame;
    
    public Controleur(MainFrame mF)
    {
        plateau = new Plateau();
        listJoueurs = new ArrayList<Joueur>();
        mainFrame = mF;
        mainFrame.setControleur(this);
    }
    
    /**
     * Fonction appelée pour démarrer une nouvelle partie
     * Reset les joueurs, le plateau et ouvre une fenêtre pour choisir le nombre de joueur de la nouvelle partie
     */
    public void nouvellePartie()
    {
        getListJoueurs().clear();
        mainFrame.getJbLancerDes().setEnabled(false);
        mainFrame.getJbProprietes().setEnabled(false);
        mainFrame.getJlValeurSolde().setText("");
        for (JLabel jl : mainFrame.getListeLabelsCase())
        {
            jl.setIcon(null);
        }
        mainFrame.getJlNom().setText("Tour de :");
        mainFrame.getJlPhoto().setIcon(null);
        newPartieFrame = new FrameNewPartie(mainFrame, true, this);
    }
    
    /**
     * Fonction qui va démarrer la partie : on permet au premier joueur de lancer les dés
     * On affiche les informations du joueur courant sur la partie gauche de la fenetre principale
     */
    public void debutPartie()
    {
        mainFrame.getJbLancerDes().setEnabled(true);
        numJoueurCourant = 0;
        joueurCourant = getListJoueurs().get(numJoueurCourant);
        mainFrame.getJbProprietes().setEnabled(true);
        mainFrame.getJlNom().setText("Tour de : " + joueurCourant.getNom());
        mainFrame.getJlPhoto().setIcon(new javax.swing.ImageIcon(getClass().getResource(joueurCourant.getPion().getBigImagePath())));
        mainFrame.getJlTextSolde().setText("solde : ");
        mainFrame.getJlValeurSolde().setText(""+joueurCourant.getSolde());
    }
    
    /**
     * Récupère le nombre de joueur et lance la fenêtre permettant de choisir le premier joueur
     * @param newPartieF 
     */
    public void choixDesJoueurs(FrameNewPartie newPartieF)
    {
        newPartieFrame = newPartieF;
        int nbJ = 0;
        if (newPartieFrame.getRb2j().isSelected()) nbJ = 2;
        else if (newPartieFrame.getRb3j().isSelected()) nbJ = 3;
        else nbJ = 4;
        
        new FrameNewPlayer(this, 1, nbJ);
        newPartieFrame.dispose();
    }
    
    /**
     * Ajoute un joueur dans la liste des joueurs de la partie
     * Et met l'icone du joueur sur la case Départ du plateau
     * @param nom
     * @param img
     * @param bigImg
     * @param numJ 
     */
    public void ajouterJoueur(String nom, String img, String bigImg, int numJ)
    {
        getListJoueurs().add(new Joueur(nom, numJ, img, bigImg, plateau.getCases().get(0), 1500));
        mainFrame.getJlDepart().setIcon(new javax.swing.ImageIcon(getClass().getResource(img)));
    }
    
    /**
     * Fonction appelée pour déplacer un joueur sur le plateau
     * Elle va regarder si le joueur est passé par la case départ, et le cas échéant lui verser le salaire
     * En fonction de la case sur laquelle le joueur est tombé :
     * Si elle est achetable, et a vendre : on lui propose de l'acheter (fenetre Oui/Non)
     * Si elle est achetable et déjà vendu : on lui dit qu'il doit payer (fenêtre d'information)
     * Si elle n'est pas achetable : la case fait son effet (pas de fenêtre d'information)
     * Puis on regarde s'il a fait un double : il rejoue
     * S'il a fait 3 doubles de suite : il va en DS
     * @param valeurDes
     * @param db 
     */
    public void avancerJoueur(int valeurDes, boolean db)
    {
        mainFrame.getJbLancerDes().setEnabled(false);
        int old_numCase = joueurCourant.getCaseCourante().getNum();
        int new_numCase = (old_numCase + valeurDes)%40;
        joueurCourant.setValeurDes(valeurDes);
        
        // passage par la case départ
        if(old_numCase < 40 && new_numCase >= 0 && new_numCase < old_numCase)
        {
            mainFrame.getJlValeurSolde().setText(""+joueurCourant.augmenterSolde(200));
        }
        
        joueurCourant.setCaseCourante(plateau.getCases().get(new_numCase));
        mainFrame.getListeLabelsCase().get(new_numCase).setIcon(new javax.swing.ImageIcon(getClass().getResource(joueurCourant.getPion().getImagePath())));
        
        boolean bIcon = false;
        
        for(Joueur j : listJoueurs)
        {
            if(!j.equals(joueurCourant))
            {
                if(j.getCaseCourante().getNum() == old_numCase)
                {
                    bIcon = true;
                    mainFrame.getListeLabelsCase().get(old_numCase).setIcon(new javax.swing.ImageIcon(getClass().getResource(j.getPion().getImagePath())));
                }
            }
        }
        
        if(!bIcon)
        {
            mainFrame.getListeLabelsCase().get(old_numCase).setIcon(null);
        }
        
        mainFrame.paint(mainFrame.getGraphics());
        
        if(joueurCourant.getCaseCourante().getNum() == 30)
        {
            try
            {
                Thread.sleep(1000);
            }
            catch(Exception e){}
            
            allerEnDS();
            joueurSuivant();
        }
        
        else
        {
            if(joueurCourant.getCaseCourante().estAchetable())
            {
                Propriete propriete = (Propriete)joueurCourant.getCaseCourante();
                if(joueurCourant.getCaseCourante().estAVendre())
                {
                    new FrameBuyProperty(mainFrame, true, this, propriete.getNom(), propriete.getPrix());
                }
                else
                {
                    int soldeAvant = joueurCourant.getSolde();
                    propriete.effet(joueurCourant, plateau);
                    int soldeApres = joueurCourant.getSolde();
                    
                    if(soldeAvant > soldeApres)
                    {
                        new FramePayment(mainFrame, true, soldeAvant-soldeApres, propriete.getProprietaire().getNom());
                    }
                }
            }
            
            else
            {
                joueurCourant.getCaseCourante().effet(joueurCourant, plateau);
            }
            
            // mise à jour des labels sur l'IHM
            Cafeteria cafet = (Cafeteria)plateau.getCases().get(20);
            mainFrame.getJlCagnotte().setText(""+cafet.getCagnotte());
            mainFrame.getJlValeurSolde().setText(""+joueurCourant.getSolde());
            
            if (db)
            {
                int cptDouble = joueurCourant.incrementerCompteDouble();
                if(cptDouble == 3)
                {
                    allerEnDS();
                    joueurSuivant();
                }
                else
                {
                    mainFrame.getJbLancerDes().setEnabled(true);
                }
            }
            else
            {
                mainFrame.getJbFinTour().setEnabled(true);
            }
        }
    }
    
    /**
     * Fonction appelée pour envoyer un joueur en DS
     * On retire son icone de la case ou il était
     * On appelle l'effet de la case "aller en DS"
     * On met son icone sur la case DS
     */
    public void allerEnDS()
    {
        mainFrame.getListeLabelsCase().get(joueurCourant.getCaseCourante().getNum()).setIcon(null);
        plateau.getCases().get(30).effet(joueurCourant, plateau);
        //joueurCourant.setCaseCourante(plateau.getCases().get(10));
        mainFrame.getListeLabelsCase().get(10).setIcon(new javax.swing.ImageIcon(getClass().getResource(joueurCourant.getPion().getImagePath())));
    }
    
    /**
     * Fonction qui initialise le joueur suivant, et met les infos correspondantes dans la partie gauche de la fenetre
     */
    public void joueurSuivant()
    {
        joueurCourant.resetCompteDouble();
            
        if (numJoueurCourant < listJoueurs.size() -1)
        {
            numJoueurCourant++;
        }
        else
        {
            numJoueurCourant = 0;
        }
        joueurCourant = listJoueurs.get(numJoueurCourant);

        mainFrame.getJlNom().setText("Tour de : " + joueurCourant.getNom());
        mainFrame.getJlPhoto().setIcon(new javax.swing.ImageIcon(getClass().getResource(joueurCourant.getPion().getBigImagePath())));
        mainFrame.getJlValeurSolde().setText(""+joueurCourant.getSolde());
        mainFrame.getJbFinTour().setEnabled(false);
        mainFrame.getJbLancerDes().setEnabled(true);
    }
    
    /**
     * Fonction appelée pour lancer les dés :
     * On choisit un nombre aléatoire pour chacun des dés, et on met à jour l'IHM (donne l'impression que les dés tournent)
     * Puis après un nombre d'itération, on fixe la valeur obtenue
     */
    public void lancerDes()
    {
        int r1, r2;
        int valeurDes = 0;
        
        boolean stop = false;
        int i = 0;
        
        boolean db = false;
        
        mainFrame.getJLabel1().setVisible(true);
        mainFrame.getJLabel3().setVisible(true);
        while(!stop)
        {
            r1 = (int)(Math.random() * (6-1)) + 1;
            r2 = (int)(Math.random() * (6-1)) + 1;
            
            mainFrame.getJLabel1().setIcon(new ImageIcon(getClass().getResource("/view/de" + r1 + ".png")));
            mainFrame.getJLabel3().setIcon(new ImageIcon(getClass().getResource("/view/de" + r2 + ".png")));
            
            mainFrame.getJPanel3().paint(mainFrame.getJPanel3().getGraphics());
            
            try
            {
                Thread.sleep(300);
                i++;
            }
            catch(Exception e){}
            if (i == 5) 
            {
                stop = true;
                valeurDes = r1+r2;
                db = (r1==r2);
            }
        }
        mainFrame.getJLabel4().setText("Vous avez fait : "+valeurDes);
        avancerJoueur(valeurDes,db);
    }
   
    /**
     * 
     * @return the plateau 
     */
    public Plateau getPlateau()
    {
        return plateau;
    }

    /**
     * @return the listJoueurs
     */
    public ArrayList<Joueur> getListJoueurs() {
        return listJoueurs;
    }

    /**
     * @return the joueurCourant
     */
    public Joueur getJoueurCourant() {
        return joueurCourant;
    }
    
    public void setJoueurCourant(Joueur value)
    {
        joueurCourant = value;
    }
}
